package com.editso.haier.util;


import com.editso.haier.exception.SuffixException;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.util.DigestUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public final class Utils {

    public static <T> List<T> arrayRange(T[] arr, int start, int end) {
        if (arr == null || arr.length < end || start >= end)
            return new ArrayList<>();
        return new ArrayList<>(Arrays.asList(arr).subList(start, end));
    }

    public static <T> List<T> asList(Iterable<T> iterable) {
        List<T> list = new ArrayList<>();
        for (T t : iterable)
            list.add(t);
        return list;
    }

    public static <T> Set<T> asSet(Iterable<T> iterable) {
        Set<T> set = new HashSet<>();
        for (T t : iterable) {
            set.add(t);
        }
        return set;
    }


    public static Map<String, Object> asMap(Pair<String, Object>... pairs) {
        Map<String, Object> map = new HashMap<>();
        for (Pair<String, Object> pair : pairs) {
            map.put(pair.getKey(), pair.getValue());
        }
        return map;
    }

    public static String get(String s, String def) {
        return s == null || "".equals(s) ? def : s;
    }

    public static void streamWrite(OutputStream out, InputStream in) throws IOException, NullPointerException {
        if (out == null || in == null)
            throw new NullPointerException();
        byte[] buff = new byte[1024 * 1024];
        int len = -1;
        while ((len = in.read(buff)) != -1) {
            out.write(buff, 0, len);
        }
    }

    public static String getSuffix(String s) {
        int i = s.lastIndexOf('.');
        if (i != -1) {
            return s.substring(i + 1);
        }
        return null;
    }


    public static String joinPath(String... paths) {
        StringBuilder buffer = new StringBuilder();
        for (String path : paths) {
            if (path.endsWith(File.separator)) {
                buffer.append(path);
            } else {
                buffer.append(File.separator).append(path);
            }
        }
        return buffer.toString();
    }

    public static String joinSuffix(String origin, String suffixName) {
        if (suffixName == null || "".equals(suffixName) || origin.endsWith(suffixName)) return origin;
        return origin.concat(".").concat(suffixName);
    }

    public static void requireMatchSuffix(String origin, String suffixName) throws SuffixException {
        if (suffixName == null) return;
        if (suffixName.startsWith(".") && origin.endsWith(suffixName)) return;
        if (origin.endsWith(".".concat(suffixName))) return;
        throw new SuffixException(origin, suffixName);
    }

    public static String md5ToString(String text) {
        return DigestUtils.md5DigestAsHex(text.getBytes());
    }

    public static String md5ToString(byte[] hex) {
        return DigestUtils.md5DigestAsHex(hex);
    }

    public static <T> Iterable<T> iterable(Iterator<T> iterator) {
        return () -> iterator;
    }


    public static String genSimpleDateCode(){
        Date date = new Date();
        return new SimpleDateFormat("YMdhms").format(date);
    }

    public static <T> Iterable<T> each(JSONArray array, Class<T> type) {
        return () -> new Iterator<T>() {
            private int pos = 0;

            @Override
            public boolean hasNext() {
                return pos < array.length();
            }

            @Override
            public T next() {
                try {
                    return (T) array.get(pos++);
                } catch (JSONException e) {
                    return null;
                }
            }
        };
    }
}
